from fastai.vision.all import *
path = untar_data(URLs.PETS)/'images'
path
Path('/home/felipe/.fastai/data/oxford-iiit-pet/images')
Path?
Init signature: Path(*args, **kwargs) Docstring: PurePath subclass that can make system calls. Path represents a filesystem path but unlike PurePath, also offers methods to do system calls on path objects. Depending on your system, instantiating a Path will return either a PosixPath or a WindowsPath object. You can also instantiate a PosixPath or WindowsPath directly, but cannot instantiate a WindowsPath on a POSIX system or vice versa. File: ~/anaconda3/envs/fastai_v2/lib/python3.7/pathlib.py Type: type Subclasses: PosixPath, WindowsPath
untar_data?
Signature: untar_data( url, fname=None, dest=None, c_key='data', force_download=False, extract_func=<function file_extract at 0x7fed08d2b0e0>, ) Docstring: Download `url` to `fname` if `dest` doesn't exist, and un-tgz or unzip to folder `dest`. File: ~/anaconda3/envs/fastai_v2/lib/python3.7/site-packages/fastai/data/external.py Type: function
URLs?
Init signature: URLs() Docstring: Global constants for dataset and model URLs. File: ~/anaconda3/envs/fastai_v2/lib/python3.7/site-packages/fastai/data/external.py Type: type Subclasses:

def is_cat(x): return x[0].isupper()
dls = ImageDataLoaders.from_name_func(
path, get_image_files(path), valid_pct=0.2, seed=42,
label_func=is_cat, item_tfms=Resize(224))
ImageDataLoaders??
Init signature: ImageDataLoaders(*loaders, path='.', device=None) Source: class ImageDataLoaders(DataLoaders): "Basic wrapper around several `DataLoader`s with factory methods for computer vision problems" @classmethod @delegates(DataLoaders.from_dblock) def from_folder(cls, path, train='train', valid='valid', valid_pct=None, seed=None, vocab=None, item_tfms=None, batch_tfms=None, **kwargs): "Create from imagenet style dataset in `path` with `train` and `valid` subfolders (or provide `valid_pct`)" splitter = GrandparentSplitter(train_name=train, valid_name=valid) if valid_pct is None else RandomSplitter(valid_pct, seed=seed) get_items = get_image_files if valid_pct else partial(get_image_files, folders=[train, valid]) dblock = DataBlock(blocks=(ImageBlock, CategoryBlock(vocab=vocab)), get_items=get_items, splitter=splitter, get_y=parent_label, item_tfms=item_tfms, batch_tfms=batch_tfms) return cls.from_dblock(dblock, path, path=path, **kwargs) @classmethod @delegates(DataLoaders.from_dblock) def from_path_func(cls, path, fnames, label_func, valid_pct=0.2, seed=None, item_tfms=None, batch_tfms=None, **kwargs): "Create from list of `fnames` in `path`s with `label_func`" dblock = DataBlock(blocks=(ImageBlock, CategoryBlock), splitter=RandomSplitter(valid_pct, seed=seed), get_y=label_func, item_tfms=item_tfms, batch_tfms=batch_tfms) return cls.from_dblock(dblock, fnames, path=path, **kwargs) @classmethod def from_name_func(cls, path, fnames, label_func, **kwargs): "Create from the name attrs of `fnames` in `path`s with `label_func`" f = using_attr(label_func, 'name') return cls.from_path_func(path, fnames, f, **kwargs) @classmethod def from_path_re(cls, path, fnames, pat, **kwargs): "Create from list of `fnames` in `path`s with re expression `pat`" return cls.from_path_func(path, fnames, RegexLabeller(pat), **kwargs) @classmethod @delegates(DataLoaders.from_dblock) def from_name_re(cls, path, fnames, pat, **kwargs): "Create from the name attrs of `fnames` in `path`s with re expression `pat`" return cls.from_name_func(path, fnames, RegexLabeller(pat), **kwargs) @classmethod @delegates(DataLoaders.from_dblock) def from_df(cls, df, path='.', valid_pct=0.2, seed=None, fn_col=0, folder=None, suff='', label_col=1, label_delim=None, y_block=None, valid_col=None, item_tfms=None, batch_tfms=None, **kwargs): "Create from `df` using `fn_col` and `label_col`" pref = f'{Path(path) if folder is None else Path(path)/folder}{os.path.sep}' if y_block is None: is_multi = (is_listy(label_col) and len(label_col) > 1) or label_delim is not None y_block = MultiCategoryBlock if is_multi else CategoryBlock splitter = RandomSplitter(valid_pct, seed=seed) if valid_col is None else ColSplitter(valid_col) dblock = DataBlock(blocks=(ImageBlock, y_block), get_x=ColReader(fn_col, pref=pref, suff=suff), get_y=ColReader(label_col, label_delim=label_delim), splitter=splitter, item_tfms=item_tfms, batch_tfms=batch_tfms) return cls.from_dblock(dblock, df, path=path, **kwargs) @classmethod def from_csv(cls, path, csv_fname='labels.csv', header='infer', delimiter=None, **kwargs): "Create from `path/csv_fname` using `fn_col` and `label_col`" df = pd.read_csv(Path(path)/csv_fname, header=header, delimiter=delimiter) return cls.from_df(df, path=path, **kwargs) @classmethod @delegates(DataLoaders.from_dblock) def from_lists(cls, path, fnames, labels, valid_pct=0.2, seed:int=None, y_block=None, item_tfms=None, batch_tfms=None, **kwargs): "Create from list of `fnames` and `labels` in `path`" if y_block is None: y_block = MultiCategoryBlock if is_listy(labels[0]) and len(labels[0]) > 1 else ( RegressionBlock if isinstance(labels[0], float) else CategoryBlock) dblock = DataBlock.from_columns(blocks=(ImageBlock, y_block), splitter=RandomSplitter(valid_pct, seed=seed), item_tfms=item_tfms, batch_tfms=batch_tfms) return cls.from_dblock(dblock, (fnames, labels), path=path, **kwargs) File: ~/anaconda3/envs/fastai_v2/lib/python3.7/site-packages/fastai/vision/data.py Type: type Subclasses:
get_image_files??
Signature: get_image_files(path, recurse=True, folders=None) Source: def get_image_files(path, recurse=True, folders=None): "Get image files in `path` recursively, only in `folders`, if specified." return get_files(path, extensions=image_extensions, recurse=recurse, folders=folders) File: ~/anaconda3/envs/fastai_v2/lib/python3.7/site-packages/fastai/data/transforms.py Type: function
dls.show_batch(figsize=(20,20))
learner = cnn_learner(dls, resnet34, metrics=error_rate)

cnn_learner?
Signature: cnn_learner( dls, arch, loss_func=None, pretrained=True, cut=None, splitter=None, y_range=None, config=None, n_out=None, normalize=True, opt_func=<function Adam at 0x7fed06a415f0>, lr=0.001, cbs=None, metrics=None, path=None, model_dir='models', wd=None, wd_bn_bias=False, train_bn=True, moms=(0.95, 0.85, 0.95), ) Docstring: Build a convnet style learner from `dls` and `arch` File: ~/anaconda3/envs/fastai_v2/lib/python3.7/site-packages/fastai/vision/learner.py Type: function
resnet34??
Signature: resnet34(pretrained=False, progress=True, **kwargs) Source: def resnet34(pretrained=False, progress=True, **kwargs): r"""ResNet-34 model from `"Deep Residual Learning for Image Recognition" <https://arxiv.org/pdf/1512.03385.pdf>`_ Args: pretrained (bool): If True, returns a model pre-trained on ImageNet progress (bool): If True, displays a progress bar of the download to stderr """ return _resnet('resnet34', BasicBlock, [3, 4, 6, 3], pretrained, progress, **kwargs) File: ~/anaconda3/envs/fastai_v2/lib/python3.7/site-packages/torchvision/models/resnet.py Type: function
dls.loss_func
FlattenedLoss of CrossEntropyLoss()
nn.CrossEntropyLoss?
Init signature: nn.CrossEntropyLoss( weight: Union[torch.Tensor, NoneType] = None, size_average=None, ignore_index: int = -100, reduce=None, reduction: str = 'mean', ) -> None Docstring: This criterion combines :func:`nn.LogSoftmax` and :func:`nn.NLLLoss` in one single class. It is useful when training a classification problem with `C` classes. If provided, the optional argument :attr:`weight` should be a 1D `Tensor` assigning weight to each of the classes. This is particularly useful when you have an unbalanced training set. The `input` is expected to contain raw, unnormalized scores for each class. `input` has to be a Tensor of size either :math:`(minibatch, C)` or :math:`(minibatch, C, d_1, d_2, ..., d_K)` with :math:`K \geq 1` for the `K`-dimensional case (described later). This criterion expects a class index in the range :math:`[0, C-1]` as the `target` for each value of a 1D tensor of size `minibatch`; if `ignore_index` is specified, this criterion also accepts this class index (this index may not necessarily be in the class range). The loss can be described as: .. math:: \text{loss}(x, class) = -\log\left(\frac{\exp(x[class])}{\sum_j \exp(x[j])}\right) = -x[class] + \log\left(\sum_j \exp(x[j])\right) or in the case of the :attr:`weight` argument being specified: .. math:: \text{loss}(x, class) = weight[class] \left(-x[class] + \log\left(\sum_j \exp(x[j])\right)\right) The losses are averaged across observations for each minibatch. Can also be used for higher dimension inputs, such as 2D images, by providing an input of size :math:`(minibatch, C, d_1, d_2, ..., d_K)` with :math:`K \geq 1`, where :math:`K` is the number of dimensions, and a target of appropriate shape (see below). Args: weight (Tensor, optional): a manual rescaling weight given to each class. If given, has to be a Tensor of size `C` size_average (bool, optional): Deprecated (see :attr:`reduction`). By default, the losses are averaged over each loss element in the batch. Note that for some losses, there are multiple elements per sample. If the field :attr:`size_average` is set to ``False``, the losses are instead summed for each minibatch. Ignored when reduce is ``False``. Default: ``True`` ignore_index (int, optional): Specifies a target value that is ignored and does not contribute to the input gradient. When :attr:`size_average` is ``True``, the loss is averaged over non-ignored targets. reduce (bool, optional): Deprecated (see :attr:`reduction`). By default, the losses are averaged or summed over observations for each minibatch depending on :attr:`size_average`. When :attr:`reduce` is ``False``, returns a loss per batch element instead and ignores :attr:`size_average`. Default: ``True`` reduction (string, optional): Specifies the reduction to apply to the output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction will be applied, ``'mean'``: the sum of the output will be divided by the number of elements in the output, ``'sum'``: the output will be summed. Note: :attr:`size_average` and :attr:`reduce` are in the process of being deprecated, and in the meantime, specifying either of those two args will override :attr:`reduction`. Default: ``'mean'`` Shape: - Input: :math:`(N, C)` where `C = number of classes`, or :math:`(N, C, d_1, d_2, ..., d_K)` with :math:`K \geq 1` in the case of `K`-dimensional loss. - Target: :math:`(N)` where each value is :math:`0 \leq \text{targets}[i] \leq C-1`, or :math:`(N, d_1, d_2, ..., d_K)` with :math:`K \geq 1` in the case of K-dimensional loss. - Output: scalar. If :attr:`reduction` is ``'none'``, then the same size as the target: :math:`(N)`, or :math:`(N, d_1, d_2, ..., d_K)` with :math:`K \geq 1` in the case of K-dimensional loss. Examples:: >>> loss = nn.CrossEntropyLoss() >>> input = torch.randn(3, 5, requires_grad=True) >>> target = torch.empty(3, dtype=torch.long).random_(5) >>> output = loss(input, target) >>> output.backward() Init docstring: Initializes internal Module state, shared by both nn.Module and ScriptModule. File: ~/anaconda3/envs/fastai_v2/lib/python3.7/site-packages/torch/nn/modules/loss.py Type: type Subclasses:
dls.train_ds
(#5912) [(PILImage mode=RGB size=500x340, TensorCategory(0)),(PILImage mode=RGB size=500x333, TensorCategory(1)),(PILImage mode=RGB size=500x332, TensorCategory(1)),(PILImage mode=RGB size=500x375, TensorCategory(0)),(PILImage mode=RGB size=500x333, TensorCategory(0)),(PILImage mode=RGB size=500x333, TensorCategory(0)),(PILImage mode=RGB size=500x375, TensorCategory(1)),(PILImage mode=RGB size=381x480, TensorCategory(0)),(PILImage mode=RGB size=300x199, TensorCategory(0)),(PILImage mode=RGB size=500x375, TensorCategory(0))...]
learner.lr_find()
SuggestedLRs(lr_min=0.006918309628963471, lr_steep=0.0003981071640737355)
learner.fit_one_cycle(5,lr_max=0.00039)
| epoch | train_loss | valid_loss | error_rate | time |
|---|---|---|---|---|
| 0 | 0.364267 | 0.033870 | 0.013532 | 00:36 |
| 1 | 0.097105 | 0.014508 | 0.004736 | 00:23 |
| 2 | 0.055072 | 0.020629 | 0.006766 | 00:23 |
| 3 | 0.029990 | 0.011130 | 0.004736 | 00:23 |
| 4 | 0.027266 | 0.011927 | 0.004736 | 00:23 |
learner.show_results(figsize=(20,20))
learner.recorder.plot_sched(figsize=(20,8))
learner.recorder.show_training_loop()
Start Fit
- before_fit : [TrainEvalCallback, Recorder, ProgressCallback]
Start Epoch Loop
- before_epoch : [Recorder, ProgressCallback]
Start Train
- before_train : [TrainEvalCallback, Recorder, ProgressCallback]
Start Batch Loop
- before_batch : []
- after_pred : []
- after_loss : []
- before_backward: []
- after_backward : []
- after_step : []
- after_cancel_batch: []
- after_batch : [TrainEvalCallback, Recorder, ProgressCallback]
End Batch Loop
End Train
- after_cancel_train: [Recorder]
- after_train : [Recorder, ProgressCallback]
Start Valid
- before_validate: [TrainEvalCallback, Recorder, ProgressCallback]
Start Batch Loop
- **CBs same as train batch**: []
End Batch Loop
End Valid
- after_cancel_validate: [Recorder]
- after_validate : [Recorder, ProgressCallback]
End Epoch Loop
- after_cancel_epoch: []
- after_epoch : [Recorder]
End Fit
- after_cancel_fit: []
- after_fit : [ProgressCallback]
import ipywidgets as widgets
uploader = widgets.FileUpload()
uploader
uploader = SimpleNamespace(data = 'figs/IMG_20200827_191930.jpg')
img = PILImage.create(uploader.data)
img